﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Lynn.Infastructure.Extension
{
    public static class EntityCopyExtension
    {
        /// <summary>
        /// 转成新的对象
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="value"></param>
        /// <param name="notcopy"></param>
        /// <returns></returns>
        public static TResult ToObject<TResult>(this object value, params string[] notcopy) where TResult : class, new()
        {
            var result = new TResult();
            Copy(ref result, value, notcopy);
            return result;
        }
        /// <summary>
        /// 拷贝
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="result"></param>
        /// <param name="value"></param>
        /// <param name="notcopy"></param>
        public static void ValueCopy<TResult>(this TResult result, object value, params string[] notcopy) where TResult : class
        {
            Copy(ref result, value, notcopy);
        }
        private static void Copy<TResult>(ref TResult result,object value, params string[] notcopy) where TResult : class {
            var pros = value.GetType().GetProperties();
            var dic = pros.Where(x => x.GetValue(value) != null).ToDictionary(x => x.Name.ToLower(), x => x.GetValue(value));
            var ps = typeof(TResult).GetProperties().Where(x => !notcopy.Contains(x.Name)).ToList();
            foreach (var item in ps)
            {
                object tmp;
                if (!dic.TryGetValue(item.Name.ToLower(), out tmp))
                {
                    continue;
                }
                var p = pros.Where(x => x.Name.ToLower() == item.Name.ToLower()).FirstOrDefault();
                if (p == null)
                {
                    continue;
                }
                var itemName = item.PropertyType.FullName;
                if (item.PropertyType.IsGenericType && item.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    itemName = item.PropertyType.GetGenericArguments()[0].FullName;
                }
                if (tmp.GetType().FullName != itemName)
                {
                    continue;
                }
                if (item.SetMethod == null) continue;
                if (itemName == "System.String")
                {
                    tmp = tmp.ToString().Trim();
                }
                item.SetValue(result, tmp);
            }
        }
    }
}
